using System;
using System.Collections;
using System.Data;
using System.Web.UI.WebControls;
using PHSRAG.Insight21.CDS;
using PHSRAG.Insight21.Common.Pages;
using PHSRAG.Insight21.Context;
using PHSRAG.Insight21.Policy;
using PHSRAG.Utility;

namespace PHSRAG.Insight21.FormsManagement
{
    /// <summary>
    /// Version page lists all the versions of the Questionnaire selected in the Questionnaire page.
    /// This page also allows the user to modify the Questionnaire, and activate any of the versions.
    /// </summary>
    public partial class Version : BasePage
    {
        #region Constants

        private const string ColumnNameActive = "IsActive";
        private const string ColumnNameDescription = "Description";
        private const string ColumnNameId = "Id";
        private const string ColumnNameVersion = "Version";
        private const string CurrentPageIndexKey = "currentPageIndexKey_3A29B061-8C7D-4387-8EBE-8CD42F1C26C1";

        private const string SelectedQuestionnaireIdKey = "SelectedQuestionnaireIdKey_3A29B061-8C7D-4387-8EBE-8CD42F1C26C1";
        private const string VersionPageKey = "versionPageKey_3A29B061-8C7D-4387-8EBE-8CD42F1C26C1";
        private const string VersionsDataSourceKey = "VersionsDataSource_3A29B061-8C7D-4387-8EBE-8CD42F1C26C1";

        #endregion

        #region Instance Variables (private)

        private ICachePolicy applicationCachePolicy;
        private ICachePolicy cachePolicy;
        private ICachePolicy pageCachePolicy;
        private RefCodes refCodes;
        private Questionnaire selectedQuestionnaire;
        private int selectedQuestionnaireId;
        private DataTable versionDataSource;

        #endregion

        #region Properties

        /// <summary>Gets or sets current page index for the grid</summary>
        private int CurrentPageIndex
        {
            get
            {
                Hashtable h = pageCachePolicy.GetCachedObject(VersionPageKey) as Hashtable;
                return (h == null || h[CurrentPageIndexKey] == null) ? 0 : (int) h[CurrentPageIndexKey];
            }
            set
            {
                Hashtable h = pageCachePolicy.GetCachedObject(VersionPageKey) as Hashtable ?? new Hashtable();
                h[CurrentPageIndexKey] = value;
                questionnaireVersions.CurrentPageIndex = value;
                pageCachePolicy.Cache(VersionPageKey, h);
            }
        }

        #endregion

        #region Events (Page)

        /// <summary>
        /// On first page load, data is pulled out of the incoming cache and is maintained
        /// by the page. Displays all the selected questionnaire related details. Loads versions 
        /// (QuestionnaireVersion objects) tied to the questionnaire and binds them to the grid.
        /// 
        /// If the questionnaire has an active version, Name, Type and Category 
        /// fields are disabled.
        /// </summary>
        /// <param name="sender">Control which rasied the event.</param>
        /// <param name="e">Arguments associated with the event.</param>
        protected void OnPageLoad(object sender, EventArgs e)
        {
            try
            {
                if (header.ModuleName == InsightUtilities.Constants.Modules.Admin)
                {
                    adminHumansSubNavigation.Visible = true;
                    coiSubNavigation.Visible = false;
                }
                else if (header.ModuleName == InsightUtilities.Constants.Modules.COI)
                {
                    adminHumansSubNavigation.Visible = false;
                    coiSubNavigation.Visible = true;
                }

                breadCrumb.Add(" Forms Management",
                    Settings.GetKeyValue("SubNavigation.Admin.humansURL", ""),
                    Settings.GetKeyValue("BreadCrumb.SummaryPageLevel", 1));

                annunciator.Message = string.Empty;
                refCodes = (RefCodes) applicationCachePolicy.GetCachedObject(RefCodes.CacheKey);

                if (!Page.IsPostBack && postbackGuard.IsValid)
                {
                    Hashtable incomingData = pageCachePolicy.GetCachedObject(Keys.IncomingDataKey) as Hashtable;
                    if (incomingData != null)
                    {
                        selectedQuestionnaireId = Convert.ToInt32(incomingData[Keys.QuestionnaireIdKey]);
                        pageCachePolicy.Cache(SelectedQuestionnaireIdKey, selectedQuestionnaireId);

                        //If arrived at from Versions page, then set the grid to show the 1st page.
                        if (incomingData.ContainsKey(Keys.FromParentPage))
                        {
                            CurrentPageIndex = 0;
                            incomingData.Remove(Keys.FromParentPage);
                        }

                        pageCachePolicy.UnCache(Keys.IncomingDataKey);
                    }
                    else
                    {
                        object o = pageCachePolicy.GetCachedObject(SelectedQuestionnaireIdKey);
                        if (o != null)
                        {
                            selectedQuestionnaireId = Convert.ToInt32(o);
                        }
                        else
                        {
                            throw new Exception("Invalid context");
                        }
                    }

                    Hashtable questionnairesList = (Hashtable) cachePolicy.GetCachedObject(Keys.QuestionnaireObjectsKey);
                    selectedQuestionnaire = (Questionnaire) questionnairesList[selectedQuestionnaireId];

                    ArrayList questionnaireTypes = refCodes.GetRefCodes(Constants.QuestionnaireType.Domain);
                    if (questionnaireTypes != null)
                    {
                        for (int i = 0, questionnaireTypeCount = questionnaireTypes.Count; i < questionnaireTypeCount; ++i)
                        {
                            RefCode refCode = (RefCode) questionnaireTypes[i];
                            questionnaireType.Items.Add(new ListItem(refCode.Meaning, refCode.Code));
                        }
                    }

                    questionnaireName.Text = selectedQuestionnaire.Name;
                    questionnaireDescription.Text = selectedQuestionnaire.Description;
                    questionnaireType.SelectedIndex = questionnaireType.Items.IndexOf(questionnaireType.Items.FindByValue(selectedQuestionnaire.Type));

                    LoadCategories(questionnaireType.SelectedValue);

                    questionnaireCategory.SelectedIndex = questionnaireCategory.Items.IndexOf(
                        questionnaireCategory.Items.FindByValue(selectedQuestionnaire.Category));
                    questionnaireCategorySequenceNo.Text = selectedQuestionnaire.CategorySequenceNo.ToString();
                    questionnaireAllowMultiple.Checked = selectedQuestionnaire.AllowMultiple;

                    CreateQuestionnaireVersionsSource();
                    pageCachePolicy.Cache(VersionsDataSourceKey, versionDataSource);
                    LoadVersionsSource();
                    BindGrid();

                    CheckForActiveVersion();
                }
                else
                {
                    selectedQuestionnaireId = Convert.ToInt32(pageCachePolicy.GetCachedObject(SelectedQuestionnaireIdKey));
                    Hashtable questionnairesList = (Hashtable) cachePolicy.GetCachedObject(Keys.QuestionnaireObjectsKey);
                    selectedQuestionnaire = (Questionnaire) questionnairesList[selectedQuestionnaireId];

                    versionDataSource = (DataTable) pageCachePolicy.GetCachedObject(VersionsDataSourceKey);
                }
                ManagePagination();
            }
            catch
            {
                annunciator.Title = InsightUtilities.Constants.Annunciator.Title;
                annunciator.Message = "Failed to load the page.";
            }
            finally
            {
                if (coiSubNavigation.Visible)
                {
                    coiSubNavigation.SelectedLink = "Forms Management";
                    coiSubNavigation.AccessLevel = ((UserContext) cachePolicy.GetCachedObject(UserContext.CacheKey)).ModuleRoleBitmask;
                }
            }
        }

        #endregion

        #region Web Form Designer generated code

        /// <summary>
        /// Page Init
        /// </summary>
        /// <param name="e">Arguments of the event</param>
        protected override void OnInit(EventArgs e)
        {
            //
            // CODEGEN: This call is required by the ASP.NET Web Form Designer.
            //
            InitializeComponent();
            base.OnInit(e);
            pageCachePolicy = (Policy.ICachePolicy) Session[Policy.Names.PageCachePolicyKey];
            cachePolicy = (Policy.ICachePolicy) Session[Policy.Names.CachePolicyKey];
            applicationCachePolicy = (Policy.ICachePolicy) Application[Policy.Names.ApplicationCachePolicyKey];
        }

        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        private void InitializeComponent()
        {
            this.header.Navigate += new System.Web.UI.WebControls.CommandEventHandler(this.OnNavigate);
            this.breadCrumb.Navigate += new System.Web.UI.WebControls.CommandEventHandler(this.OnNavigate);
            this.topPager.FirstPage += new System.Web.UI.WebControls.CommandEventHandler(this.OnFirstPage);
            this.topPager.PreviousPage += new System.Web.UI.WebControls.CommandEventHandler(this.OnPreviousPage);
            this.topPager.NextPage += new System.Web.UI.WebControls.CommandEventHandler(this.OnNextPage);
            this.topPager.LastPage += new System.Web.UI.WebControls.CommandEventHandler(this.OnLastPage);
            this.questionnaireVersions.ItemCommand += new System.Web.UI.WebControls.DataGridCommandEventHandler(this.OnQuestionnaireVersionsItemCommand);
            this.questionnaireVersions.ItemDataBound += new System.Web.UI.WebControls.DataGridItemEventHandler(this.OnQuestionnaireVersionsItemDataBound);
            this.bottomPager.FirstPage += new System.Web.UI.WebControls.CommandEventHandler(this.OnFirstPage);
            this.bottomPager.PreviousPage += new System.Web.UI.WebControls.CommandEventHandler(this.OnPreviousPage);
            this.bottomPager.NextPage += new System.Web.UI.WebControls.CommandEventHandler(this.OnNextPage);
            this.bottomPager.LastPage += new System.Web.UI.WebControls.CommandEventHandler(this.OnLastPage);
            this.ID = "versionDescription";
            this.Load += new System.EventHandler(this.OnPageLoad);
        }

        #endregion

        #region Events (Controls)

        /// <summary>
        /// Occurs when the FirstPage hyperlink is clicked on the pager.
        /// The grid is reloaded with the data pertaining to the first page.
        /// </summary>
        /// <param name="sender">Control which raised the event.</param>
        /// <param name="e">Arguments associated with the event.</param>
        private void OnFirstPage(object sender, CommandEventArgs e)
        {
            try
            {
                if (!postbackGuard.IsValid)
                {
                    return;
                }
                CurrentPageIndex = 0;
                BindGrid();
                ManagePagination();
            }
            catch
            {
                annunciator.Title = InsightUtilities.Constants.Annunciator.Title;
                annunciator.Message = "Error occurred while loading the first page.";
            }
        }

        /// <summary>
        /// Occurs when the LastPage hyperlink is clicked on the pager.
        /// The grid is reloaded with the data pertaining to the last page.
        /// </summary>
        /// <param name="sender">Control which raised the event.</param>
        /// <param name="e">Arguments associated with the event.</param>
        private void OnLastPage(object sender, CommandEventArgs e)
        {
            try
            {
                if (!postbackGuard.IsValid)
                {
                    return;
                }
                CurrentPageIndex = topPager.PageCount - 1;
                BindGrid();
                ManagePagination();
            }
            catch
            {
                annunciator.Title = InsightUtilities.Constants.Annunciator.Title;
                annunciator.Message = "Error occurred while loading the last page.";
            }
        }

        /// <summary>
        /// Occurs when the NexttPage hyperlink is clicked on the pager.
        /// The grid is reloaded with the data pertaining to the next page.
        /// </summary>
        /// <param name="sender">Control which raised the event.</param>
        /// <param name="e">Arguments associated with the event.</param>
        private void OnNextPage(object sender, CommandEventArgs e)
        {
            try
            {
                if (!postbackGuard.IsValid)
                {
                    return;
                }
                ++CurrentPageIndex;
                BindGrid();
                ManagePagination();
            }
            catch
            {
                annunciator.Title = InsightUtilities.Constants.Annunciator.Title;
                annunciator.Message = "Error occurred while loading the next page.";
            }
        }

        /// <summary>
        /// Occurs when the PreviousPage hyperlink is clicked on the pager.
        /// The grid is reloaded with the data pertaining to the previous page.
        /// </summary>
        /// <param name="sender">Control which raised the event.</param>
        /// <param name="e">Arguments associated with the event.</param>
        private void OnPreviousPage(object sender, CommandEventArgs e)
        {
            try
            {
                if (!postbackGuard.IsValid)
                {
                    return;
                }
                --CurrentPageIndex;
                BindGrid();
                ManagePagination();
            }
            catch
            {
                annunciator.Title = InsightUtilities.Constants.Annunciator.Title;
                annunciator.Message = "Error occurred while loading the previous page.";
            }
        }

        /// <summary>
        /// If a version is active, then the client id of the radio button for the row diplaying the active version details is stored in
        /// a hidden field. This hidden field helps in restraining the selection to only one radio button.
        /// </summary>
        /// <param name="sender">Control that raised the event.</param>
        /// <param name="e">Arguments associated with the event.</param>
        private void OnQuestionnaireVersionsItemDataBound(object sender, DataGridItemEventArgs e)
        {
            try
            {
                if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
                {
                    RadioButton versionActive = (RadioButton) e.Item.FindControl("versionActive");
                    DataRow row = ((DataRowView) e.Item.DataItem).Row;
                    if ((bool) row["IsActive"])
                    {
                        activeVersionTracker.Value = versionActive.ClientID;
                    }
                    versionActive.Attributes.Add("OnClick", "javascript:RestrictActiveVersionSelection('" + versionActive.ClientID + "')");
                }
            }
            catch
            {
                annunciator.Title = InsightUtilities.Constants.Annunciator.Title;
                annunciator.Message = "Error occurred while loading the questionnaires grid";
            }
        }

        /// <summary>
        /// Displays the UI to create a new version
        /// </summary>
        /// <param name="sender">Control that raised the event.</param>
        /// <param name="e">Arguments associated with the event.</param>
        protected void OnCreateVersionClick(object sender, EventArgs e)
        {
            try
            {
                versionsPanel.Visible = false;
                createVersionPanel.Visible = true;
            }
            catch (Exception ex)
            {
                DisplayExceptionReport(ex);
            }
        }

        /// <summary>
        /// Saves the new version and adds it to the selected questionnaire's versions collection
        /// </summary>
        /// <param name="sender">Control that raised the event.</param>
        /// <param name="e">Arguments associated with the event.</param>
        protected void OnSaveVersionClick(object sender, EventArgs e)
        {
            try
            {
                if (postbackGuard.IsValid)
                {
                    QuestionnaireVersion newVersion = selectedQuestionnaire.CreateVersion(cachePolicy);
                    newVersion.Description = newVersionDescription.Text.Trim();
                    selectedQuestionnaire.Save(DataAccess.ConnectionString);
                    AddVersionToGridSource(newVersion);
                    versionsPanel.Visible = true;
                    createVersionPanel.Visible = false;
                    BindGrid();
                    ManagePagination();
                }
            }
            catch
            {
                annunciator.Title = InsightUtilities.Constants.Annunciator.Title;
                annunciator.Message = "Could not save the Questionnaire Version.";
            }
        }

        /// <summary>
        /// Updates the changes made to all the versions listed in the grid
        /// </summary>
        /// <param name="sender">Control that raised the event.</param>
        /// <param name="e">Arguments associated with the event.</param>
        protected void OnUpdateQuestionnaireClick(object sender, EventArgs e)
        {
            try
            {
                if (!postbackGuard.IsValid)
                {
                    return;
                }
                string currentQuestionnaireName = questionnaireName.Text.Trim();
                if (DoesQuestionnaireExist(currentQuestionnaireName, selectedQuestionnaire.Id))
                {
                    annunciator.Message = "A Questionnaire with the specified name already exists. Enter another name.";
                    return;
                }
                selectedQuestionnaire.Name = currentQuestionnaireName;
                selectedQuestionnaire.Description = questionnaireDescription.Text.Trim();
                selectedQuestionnaire.Type = questionnaireType.SelectedValue;
                selectedQuestionnaire.Category = questionnaireCategory.SelectedValue;
                string sequenceNo = questionnaireCategorySequenceNo.Text.Trim();
                selectedQuestionnaire.CategorySequenceNo = (sequenceNo == string.Empty) ? 0 : int.Parse(sequenceNo);
                selectedQuestionnaire.AllowMultiple = questionnaireAllowMultiple.Checked;
                //set active version
                for (int i = 0; i < questionnaireVersions.Items.Count; ++i)
                {
                    QuestionnaireVersion questionnaireVersion = selectedQuestionnaire.GetQuestionnaireVersionById(int.Parse(((Label) questionnaireVersions.Items[i].FindControl("questionnaireVersionID")).Text));
                    selectedQuestionnaire.Active |= questionnaireVersion.IsActive = ((RadioButton) questionnaireVersions.Items[i].FindControl("versionActive")).Checked;
                    questionnaireVersion.Description = ((TextBox) questionnaireVersions.Items[i].FindControl("versionDescription")).Text.Trim();
                }
                selectedQuestionnaire.Save(DataAccess.GetConnectionString());
                CheckForActiveVersion();
                LoadVersionsSource();
                BindGrid();
            }
            catch
            {
                annunciator.Title = InsightUtilities.Constants.Annunciator.Title;
                annunciator.Message = "Could not update Questionnaire Versions.";
            }
        }

        /// <summary>
        /// Redirects the user to the Questionnaire page
        /// </summary>
        /// <param name="sender">Control that raised the event.</param>
        /// <param name="e">Arguments associated with the event.</param>
        protected void OnBackClick(object sender, EventArgs e)
        {
            try
            {
                Response.Redirect("Questionnaire.aspx", false);
            }
            catch (Exception ex)
            {
                DisplayExceptionReport(ex);
            }
        }

        /// <summary>
        /// Stores Id's of selected questionnaire and version objects and redirects the user to FormEditor page.
        /// </summary>
        /// <param name="source">Control that raised the event.</param>
        /// <param name="e">Arguments associated with the event.</param>
        private void OnQuestionnaireVersionsItemCommand(object source, DataGridCommandEventArgs e)
        {
            try
            {
                if (!postbackGuard.IsValid)
                {
                    return;
                }
                if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
                {
                    Hashtable outgoingData = new Hashtable();
                    outgoingData.Add(Keys.QuestionnaireIdKey, selectedQuestionnaireId);
                    outgoingData.Add(Keys.QuestionnaireVersionIdKey, int.Parse(((Label) e.Item.FindControl("questionnaireVersionID")).Text));
                    outgoingData.Add(Keys.FromParentPage, true);
                    pageCachePolicy.Cache(Keys.IncomingDataKey, outgoingData);
                    Response.Redirect(Settings.GetKeyValue("SubNavigation.Admin.Humans.FormEditorURL", "FormEditor.aspx"), false);
                }
            }
            catch
            {
                annunciator.Title = InsightUtilities.Constants.Annunciator.Title;
                annunciator.Message = "Error occurred while redirecting to the Form Editor page.";
            }
        }

        /// <summary>
        /// Loads categories based on the selected type
        /// </summary>
        /// <param name="sender">Control that raised the event.</param>
        /// <param name="e">Arguments associated with the event.</param>
        protected void OnQuestionnaireTypeSelectedIndexChanged(object sender, EventArgs e)
        {
            try
            {
                if (!postbackGuard.IsValid)
                {
                    return;
                }
                questionnaireCategory.Items.Clear();
                LoadCategories(questionnaireType.SelectedValue);
            }
            catch
            {
                annunciator.Title = InsightUtilities.Constants.Annunciator.Title;
                annunciator.Message = "Error occurred while loading the categories for the selected questionnaire type.";
            }
        }

        /// <summary>
        /// Cancels creation of new version
        /// </summary>
        /// <param name="sender">Control that raised the event.</param>
        /// <param name="e">Arguments associated with the event.</param>
        protected void OnCancelVersionClick(object sender, EventArgs e)
        {
            try
            {
                versionsPanel.Visible = true;
                createVersionPanel.Visible = false;
                newVersionDescription.Text = string.Empty;
            }
            catch (Exception ex)
            {
                DisplayExceptionReport(ex);
            }
        }

        /// <summary>
        /// Resets the subnavigation selected link before the header or the breadCrumb performs a redirect.
        /// </summary>
        /// <param name="sender">Control that raised the event.</param>
        /// <param name="e">Arguments associated with the event.</param>
        private void OnNavigate(object sender, CommandEventArgs e)
        {
            try
            {
                adminSubNavigation.Reset();
                adminHumansSubNavigation.Reset();
                coiSubNavigation.Reset();
            }
            catch (Exception ex)
            {
                DisplayExceptionReport(ex);
            }
        }

        #endregion

        #region Private methods

        /// <summary>
        /// Displays an error message on the screen to the user with the exception, and all
        /// inner exception messages.
        /// </summary>
        /// <param name="ex">The exception to report on</param>
        private void DisplayExceptionReport(Exception ex)
        {
            annunciator.Title = InsightUtilities.Constants.Annunciator.Title;
            annunciator.Message = ExceptionReport.GetExceptionInfo(ex, false);
        }

        /// <summary>
        /// Enables or Disables links to other pages of the grid on the pager controls
        /// </summary>
        private void ManagePagination()
        {
            int currentPageIndex = CurrentPageIndex;
            questionnaireVersions.CurrentPageIndex = currentPageIndex;

            int startIndex = currentPageIndex*questionnaireVersions.PageSize;
            bottomPager.FirstRecord = topPager.FirstRecord = startIndex + 1;

            int lastRecord = versionDataSource.Rows.Count;
            bottomPager.LastRecord = topPager.LastRecord =
                Math.Min(startIndex + questionnaireVersions.PageSize, lastRecord);

            bottomPager.EnableFirstPage = topPager.EnableFirstPage =
                bottomPager.EnablePreviousPage = topPager.EnablePreviousPage =
                    (questionnaireVersions.CurrentPageIndex != 0);

            bottomPager.EnableLastPage = topPager.EnableLastPage =
                bottomPager.EnableNextPage = topPager.EnableNextPage =
                    (questionnaireVersions.CurrentPageIndex != (topPager.PageCount - 1));
        }

        /// <summary>
        /// Creates a datatable containing the details of all the questionnaire versions. This table acts as the DataSource for the grid.
        /// The reason behind having a seperate table to bind versions instead of using the already existing hashtable is 
        /// because of the order of objects stored inside the hashtable.
        /// </summary>
        private void CreateQuestionnaireVersionsSource()
        {
            versionDataSource = new DataTable();
            versionDataSource.Columns.Add(ColumnNameId, typeof (int));
            versionDataSource.Columns.Add(ColumnNameVersion, typeof (int));
            versionDataSource.Columns.Add(ColumnNameActive, typeof (bool));
            versionDataSource.Columns.Add(ColumnNameDescription);
        }

        /// <summary>
        /// Loads all the version object's details from hashtable to versionDataSource
        /// </summary>
        private void LoadVersionsSource()
        {
            versionDataSource.Rows.Clear();
            foreach (QuestionnaireVersion qv in selectedQuestionnaire.Versions)
            {
                AddVersionToGridSource(qv);
            }
        }

        /// <summary>
        /// Adds a version object as a row to versionDataSource
        /// </summary>
        /// <param name="version">QuestionnaireVersion object</param>
        private void AddVersionToGridSource(QuestionnaireVersion version)
        {
            DataRow row = versionDataSource.NewRow();
            row[ColumnNameId] = version.Id;
            row[ColumnNameVersion] = version.Version;
            row[ColumnNameActive] = version.IsActive;
            row[ColumnNameDescription] = version.Description;
            versionDataSource.Rows.Add(row);
        }

        /// <summary>
        /// Binds the selected questionnaire's versions to the datagrid
        /// </summary>
        private void BindGrid()
        {
            questionnaireVersions.VirtualItemCount = bottomPager.RecordCount =
                topPager.RecordCount = versionDataSource.Rows.Count;

            int currentPageIndex = CurrentPageIndex;
            int pageCount = (topPager.RecordCount/questionnaireVersions.PageSize) +
                (((topPager.RecordCount%questionnaireVersions.PageSize) == 0) ? 0 : 1);
            bottomPager.PageCount = topPager.PageCount = pageCount;
            bottomPager.CurrentPage = topPager.CurrentPage = currentPageIndex + 1;

            DataTable table = GetVersionsForGridPage(currentPageIndex*questionnaireVersions.PageSize, questionnaireVersions.PageSize);

            questionnaireVersions.DataSource = table;
            questionnaireVersions.DataBind();
        }

        /// <summary>
        /// Gets the versions that need to be displayed for a specific page of the grid
        /// </summary>
        /// <param name="startIndex">The grid's current page first record index</param>
        /// <param name="pageSize">The number of records displayed in a grid's page</param>
        /// <returns>Versions to be displayed in the current page of the grid</returns>
        private DataTable GetVersionsForGridPage(int startIndex, int pageSize)
        {
            DataTable pagedResults = versionDataSource.Clone();

            DataView versionsView = versionDataSource.DefaultView;
            versionsView.Sort = ColumnNameVersion + " DESC";
            for (int m = startIndex, endIndex = Math.Min(versionsView.Count, startIndex + pageSize); m < endIndex; ++m)
            {
                pagedResults.ImportRow(versionsView[m].Row);
            }
            return pagedResults;
        }

        /// <summary>
        /// Checks if any other questionnaire with the specified name already exists in the collection of questionnaires
        /// </summary>
        /// <param name="name">Modified name of the questionnaire</param>
        /// <param name="id">Id of the questionnaire being modified</param>
        /// <returns>true, if any other questionnaire with the specified name already exists</returns>
        private bool DoesQuestionnaireExist(string name, int id)
        {
            Hashtable questionnairesList = (Hashtable) cachePolicy.GetCachedObject(Keys.QuestionnaireObjectsKey);
            foreach (Questionnaire q in questionnairesList.Values)
            {
                if (q.Name == name && q.Id != id)
                {
                    return true;
                }
            }
            return false;
        }

        /// <summary>
        /// Checks if any of the versions are active. If so, disables the name, type and category fields of questionnaire.
        /// </summary>
        private void CheckForActiveVersion()
        {
            if (selectedQuestionnaire.Versions != null)
            {
                bool activeVersionFound = false;
                foreach (QuestionnaireVersion qV in selectedQuestionnaire.Versions)
                {
                    if (qV.IsActive)
                    {
                        activeVersionFound = true;
                        break;
                    }
                }
                if (activeVersionFound)
                {
                    questionnaireName.Enabled = false;
                    questionnaireType.Enabled = false;
                    questionnaireCategory.Enabled = false;
                }
            }
        }

        /// <summary>
        /// Loads the categories based on the form type selected
        /// </summary>
        /// <param name="selectedTypeValue">refcode for the selected form type</param>
        private void LoadCategories(string selectedTypeValue)
        {
            RefCode refCode = refCodes.GetRefCode(selectedTypeValue);

            string categoryDomainForSelectedType = refCode.Attributes[Constants.QuestionnaireType.CategoryAttribute].ToString();

            ArrayList questionnaireCategories = refCodes.GetRefCodes(categoryDomainForSelectedType);
            if (questionnaireCategories != null)
            {
                int questionnaireCategoryCount = questionnaireCategories.Count;
                for (int i = 0; i < questionnaireCategoryCount; ++i)
                {
                    refCode = (RefCode) questionnaireCategories[i];
                    questionnaireCategory.Items.Add(new ListItem(refCode.Meaning, refCode.Code));
                }
            }
        }

        #endregion
    }
}